package com.chb.jwt;

import com.alibaba.fastjson.JSON;
import com.chb.base.UserInfo;
import com.chb.common.CommonConstants;
import com.chb.entity.SecurityUserInfo;
import com.chb.redis.RedisService;
import com.chb.utils.BeanUtils;
import com.chb.utils.JwtUtils;
import com.chb.utils.UserInfoContext;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    private static final String WEB_TOKEN_PRE = "token";
    @Resource
    private RedisService redisService;
    @Resource
    private UserDetailsService userDetailsService;
    @Resource
    private JwtUtils jwtUtils;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        // 判断是否携带token
        String token = request.getHeader(WEB_TOKEN_PRE);
        if(StringUtils.isEmpty(token)){
            // 判断参数中是否携带token
            token = request.getParameter(WEB_TOKEN_PRE);
            if(StringUtils.isEmpty(token)){
                log.info("未携带token");
                chain.doFilter(request,response);
                return;
            }
        }
        Claims claims = jwtUtils.getClaims(token);
        String errorMsg = "token 失效";
        if(claims == null){
            log.info(errorMsg);
            chain.doFilter(request,response);
            return;
        }
        String userName = (String) claims.get("name");
        // 取出redis中用户信息
        String userInfoString = (String)redisService.get(String.format(CommonConstants.LOGIN_TOKEN_PREFIX, userName.toUpperCase()));
        if(StringUtils.isEmpty(userInfoString)){
            log.info(errorMsg);
            chain.doFilter(request,response);
            return;
        }
        // 放入threadLocal
        UserInfo userInfo  = JSON.toJavaObject(JSON.parseObject(userInfoString), UserInfo.class);
        UserInfoContext.setUserInfo(userInfo);
        // 将验证过的用户信息放入security上下文 供后方鉴权过滤器使用
        SecurityUserInfo securityUserInfo = BeanUtils.copyBean(userInfo, SecurityUserInfo::new);
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(securityUserInfo, null, securityUserInfo.getAuthorities());
        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        chain.doFilter(request,response);
    }

    public static void main(String[] args) {
        String a = "{\"authorities\":[{\"authority\":\"man\"},{\"authority\":\"lion\"}],\"name\":\"man\",\"permissionList\":[\"man\",\"lion\"],\"phone\":\"15845362997\",\"pwd\":\"$2a$10$7WU7BjEB0IAr.LcodApKZeOQ6n40QzLeZgeo7eM.URtMzujvO6Oc.\",\"sex\":1,\"userId\":2}";
        a.replace("\\","");
        System.out.println(a);
        Object parse = JSON.parse(a);
        System.out.println(parse);
        UserInfo userInfo = JSON.toJavaObject(JSON.parseObject(a), UserInfo.class);
        SecurityUserInfo securityUserInfo = BeanUtils.copyBean(userInfo,SecurityUserInfo::new);
        System.out.println(securityUserInfo.getAuthorities());
    }
}
